package com.alexsh.web;

import com.alexsh.service.BookManager;
import com.alexsh.service.bookspresentation.BookType;
import com.alexsh.web.form.BookFormBean;
import com.alexsh.web.form.validator.AddBookValidator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;

/**
 * @author Alexander Shmygin <AShmygin@luxoft.com>
 * @version 1.0
 */
@Controller
public class BookController extends MenuController {

    private static final Log logger = LogFactory.getLog(BookController.class);

    private static final String ADD_BOOK_FORM_BEAN = "addBookFormBean";

    @Autowired
    BookManager bookManager;

    @RequestMapping("/viewBook")
    public ModelAndView viewBook() {
        ModelAndView mav = new ModelAndView("viewBook");
        BookFormBean formBean = new BookFormBean();
        try {
            formBean.setContent(bookManager.getBookList(BookType.JSON));
        } catch (Exception e) {
            logger.error("Exception happened when trying to get book list. ", e);
        }
        mav.addObject("pageContent", formBean);
        return mav;
    }

    @ModelAttribute("getBooksJsonForTable")
    public String getBooksJsonForTable(HttpServletResponse response) throws JSONException {
        return bookManager.getBookList(BookType.JSON);
    }

    @RequestMapping("/getBooksJson")
    public String getBooksJson(HttpServletResponse response) throws JSONException {
        String json = bookManager.getBookList(BookType.JSON);
        setResponse(json, response);
        return "";
    }

    @RequestMapping("/getBooksXml")
    public String getBooksXml(HttpServletResponse response) {
        String xml = bookManager.getBookList(BookType.XML);
        setResponse(xml, response);
        return "";
    }

    @RequestMapping("/getBookByIdJson")
    public String getBookByIdJson(@RequestParam("bookId") String bookId,
                                  HttpServletResponse response) {
        String json = bookManager.getBookById(bookId, BookType.JSON);
        setResponse(json, response);
        return "";
    }

    @RequestMapping("/getBookByIdXml")
    public String getBookByIdXml(@RequestParam("bookId") String bookId,
                                 HttpServletResponse response) {
        String xml = bookManager.getBookById(bookId, BookType.XML);
        setResponse(xml, response);
        return "";
    }

    @RequestMapping("/addBook")
    public ModelAndView addBook() {
        ModelAndView mav = new ModelAndView("addBook");
        BookFormBean formBean = new BookFormBean();
        mav.addObject(ADD_BOOK_FORM_BEAN, formBean);
        return mav;
    }

    @RequestMapping("/saveNewBook")
    public ModelAndView saveBook(@ModelAttribute(ADD_BOOK_FORM_BEAN)
    BookFormBean formBean, BindingResult errors, HttpServletResponse response) {
        new AddBookValidator().validate(formBean, errors);
        if (!errors.hasErrors()) {
            bookManager.saveBook(formBean);
            setResponse("Book " + formBean.getAuthors() + " - " + formBean.getTitle()
                + " has been saved successfully.", response);
            logger.debug("New book has been saved successfully.\n" + setSaveBookInformation(formBean));
            return new ModelAndView();
        }
        ModelAndView mav = new ModelAndView("addBook");
        mav.addObject(ADD_BOOK_FORM_BEAN, formBean);
        return mav;
    }

    @RequestMapping("/deleteBook")
    public String deleteBook(@RequestParam("bookId") String bookId,
                             HttpServletResponse response) {
        bookManager.deleteBookById(bookId);
        setResponse("Book with ID=" + bookId + " has been deleted successfully.", response);
        return "";
    }

    private String setSaveBookInformation(BookFormBean formBean) {
        return "Title: " + formBean.getTitle() + ",\nAuthors: "
            + formBean.getAuthors() + ",\nPublication Date: " + formBean.getPubDate();
    }

    private void setResponse(String content, HttpServletResponse response) {
        try {
            response.getWriter().print(content);
            response.getWriter().flush();
        } catch (Exception e) {
            logger.error(e);
        }
    }
}
